#include "commit_file_to_url_command.h"
#include "service/backend_service.h"
#include "../database/database_manager.h"
#include "service/web_socket_server.h"
#include "command_executor.h"
#include <QDebug>
#include <QUrl>
#include <QFile>
#include <QFileInfo>
#include <QHttpMultiPart>
#include <QHttpPart>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>

CommitFileToUrlCommand::CommitFileToUrlCommand(QObject *parent)
    : QObject(parent)
    , m_backendService(nullptr)
    , m_networkManager(nullptr)
    , m_databaseManager(nullptr)
    , m_webSocketServer(nullptr)
{
}

CommitFileToUrlCommand::~CommitFileToUrlCommand()
{
    // 断开网络请求完成信号连接
    if (m_networkManager) {
        // disconnect(m_networkManager, &QNetworkAccessManager::finished,
        //            this, &CommitFileToUrlCommand::handleUploadResponse);
    }
}

void CommitFileToUrlCommand::setBackendService(BackendService *backendService)
{
    m_backendService = backendService;
}

void CommitFileToUrlCommand::setNetworkAccessManager(QNetworkAccessManager *networkManager)
{
    // 如果之前已经设置了 networkManager，先断开旧的连接
    if (m_networkManager) {
        disconnect(m_networkManager, &QNetworkAccessManager::finished,
                   this, &CommitFileToUrlCommand::handleUploadResponse);
    }
    
    m_networkManager = networkManager;
    
    // 连接网络请求完成信号
    if (m_networkManager) {
        connect(m_networkManager, &QNetworkAccessManager::finished,
                this, &CommitFileToUrlCommand::handleUploadResponse);
    }
}

void CommitFileToUrlCommand::setDatabaseManager(DatabaseManager *databaseManager)
{
    m_databaseManager = databaseManager;
}

void CommitFileToUrlCommand::setWebSocketServer(WebSocketServer *webSocketServer)
{
    m_webSocketServer = webSocketServer;
}

bool CommitFileToUrlCommand::execute(const QString &commitUrl, const QString &localFilePath, const QString &accessToken)
{
    qDebug() << "CommitFileToUrlCommand: 准备提交文件，URL:" << commitUrl << "文件路径:" << localFilePath;
    
    // 验证URL
    if (commitUrl.isEmpty()) {
        qDebug() << "CommitFileToUrlCommand: 提交URL为空";
        return false;
    }
    
    // 验证URL格式
    QUrl url(commitUrl);
    if (!url.isValid()) {
        qDebug() << "CommitFileToUrlCommand: 无效的提交URL:" << commitUrl;
        return false;
    }
    
    // 验证文件路径
    if (localFilePath.isEmpty()) {
        qDebug() << "CommitFileToUrlCommand: 文件路径为空";
        return false;
    }
    
    // 检查文件是否存在
    QFile localFile(localFilePath);
    if (!localFile.exists()) {
        qDebug() << "CommitFileToUrlCommand: 本地文件不存在:" << localFilePath;
        return false;
    }
    
    // 读取文件内容
    if (!localFile.open(QIODevice::ReadOnly)) {
        qDebug() << "CommitFileToUrlCommand: 无法打开本地文件:" << localFile.errorString();
        return false;
    }
    
    QByteArray fileContent = localFile.readAll();
    localFile.close();
    
    qDebug() << "CommitFileToUrlCommand: 文件内容大小:" << fileContent.size() << "字节";
    
    if (!m_networkManager) {
        qDebug() << "CommitFileToUrlCommand: QNetworkAccessManager 未设置";
        return false;
    }
    
    // 创建网络请求
    QNetworkRequest request;
    request.setUrl(url);
    
    // 添加 accessToken 到请求头
    if (!accessToken.isEmpty()) {
        // 如果传入了 accessToken 参数，使用传入的 token
        request.setRawHeader("accessToken", accessToken.toUtf8());
        qDebug() << "CommitFileToUrlCommand: 已添加传入的accessToken到请求头";
    } else {
        // 否则从 CommandExecutor 获取 accessToken（作为后备）
        QString tokenFromService = CommandExecutor::getAccessToken();
            if (!tokenFromService.isEmpty()) {
                request.setRawHeader("accessToken", tokenFromService.toUtf8());
            qDebug() << "CommitFileToUrlCommand: 已添加CommandExecutor的accessToken到请求头";
        } else {
            qDebug() << "CommitFileToUrlCommand: CommandExecutor 的 accessToken 为空";
        }
    }
    
    // 创建多部分数据
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    
    // 获取文件名
    QFileInfo fileInfo(localFilePath);
    QString fileName = fileInfo.fileName();
    
    // 创建文件部分
    QHttpPart filePart;
    filePart.setHeader(QNetworkRequest::ContentDispositionHeader, 
                      QVariant("form-data; name=\"files\"; filename=\"" + fileName + "\""));
    filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
    filePart.setBody(fileContent);
    
    multiPart->append(filePart);
    
    // 发送POST请求
    QNetworkReply *reply = m_networkManager->post(request, multiPart);
    multiPart->setParent(reply); // 确保在reply删除时也删除multiPart
    
    // 设置请求类型标识
    reply->setProperty("requestType", "commitFile");
    reply->setProperty("localFilePath", localFilePath);
    reply->setProperty("commitUrl", commitUrl);
    
    // 请求已成功发送，更新状态为 PROCESSING
    if (m_databaseManager && !commitUrl.isEmpty()) {
        if (m_databaseManager->updateCommandStatusByCommitUrl(commitUrl, "commitfiletourl", "PROCESSING")) {
            qDebug() << "CommitFileToUrlCommand: 成功更新命令记录状态为 PROCESSING，提交URL:" << commitUrl;
        } else {
            qDebug() << "CommitFileToUrlCommand: 更新命令记录状态失败，提交URL:" << commitUrl;
        }
    }
    
    qDebug() << "CommitFileToUrlCommand: 文件提交请求已发送，URL:" << commitUrl;
    
    return true;
}

void CommitFileToUrlCommand::handleUploadResponse(QNetworkReply *reply)
{
    if (!reply) {
        qDebug() << "CommitFileToUrlCommand: 上传响应为空";
        emit fileCommitCompleted(-1, "上传响应为空");
        return;
    }
    
    QString requestType = reply->property("requestType").toString();
    if (requestType != "commitFile") {
        // 不是文件提交请求，忽略
        reply->deleteLater();
        return;
    }
    
    QString localFilePath = reply->property("localFilePath").toString();
    QString commitUrl = reply->property("commitUrl").toString();
    
    qDebug() << "CommitFileToUrlCommand: 处理文件提交响应，错误:" << reply->error() 
             << "文件路径:" << localFilePath;
    
    if (reply->error() == QNetworkReply::NoError) {
        // 读取响应数据
        QByteArray responseData = reply->readAll();
        qDebug() << "CommitFileToUrlCommand: 文件提交成功，响应数据大小:" << responseData.size() << "字节";
        
        // 尝试解析JSON响应
        QJsonParseError parseError;
        QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData, &parseError);
        
        if (parseError.error == QJsonParseError::NoError && jsonDoc.isObject()) {
            QJsonObject response = jsonDoc.object();
            int errcode = response["errcode"].toInt();
            QString errmsg = response["errmsg"].toString();
            
            qDebug() << "CommitFileToUrlCommand: 文件提交响应 - errcode:" << errcode << "errmsg:" << errmsg;
            
            // 根据执行结果更新 kms_command.STATUS
            if (m_databaseManager && !commitUrl.isEmpty()) {
                QString status = (errcode == 0) ? "COMPLETED" : "FAILED";
                if (m_databaseManager->updateCommandStatusByCommitUrl(commitUrl, "commitfiletourl", status)) {
                    qDebug() << "CommitFileToUrlCommand: 成功更新命令记录状态，提交URL:" << commitUrl << "状态:" << status;
                } else {
                    qDebug() << "CommitFileToUrlCommand: 更新命令记录状态失败，提交URL:" << commitUrl;
                }
            }

            if (errcode == 0) {
                qDebug() << "CommitFileToUrlCommand: 文件提交成功:" << errmsg;               
                // 通过 WebSocket 发送 refresh 消息到客户端
                if (m_webSocketServer) {
                    QJsonObject refreshMessage;
                    refreshMessage["command"] = "refresh";
                    QJsonDocument doc(refreshMessage);
                    QString message = doc.toJson(QJsonDocument::Compact);
                    m_webSocketServer->broadcastMessage(message);
                    qDebug() << "CommitFileToUrlCommand: 已通过 WebSocket 发送 refresh 消息到客户端";
                } else {
                    qDebug() << "CommitFileToUrlCommand: WebSocketServer 未设置，无法发送 refresh 消息";
                }
                
                // 提交成功后删除本地文件
                if (!localFilePath.isEmpty()) {
                    QFile localFile(localFilePath);
                    if (localFile.exists()) {
                        if (localFile.remove()) {
                            qDebug() << "CommitFileToUrlCommand: 成功删除本地文件:" << localFilePath;
                        } else {
                            qDebug() << "CommitFileToUrlCommand: 删除本地文件失败:" << localFilePath 
                                     << "错误:" << localFile.errorString();
                        }
                    } else {
                        qDebug() << "CommitFileToUrlCommand: 本地文件不存在，无需删除:" << localFilePath;
                    }
                }
                
                emit fileCommitCompleted(0, "文件提交成功: " + errmsg);
            } else {
                qDebug() << "CommitFileToUrlCommand: 文件提交失败:" << errmsg;
                emit fileCommitCompleted(errcode, "文件提交失败: " + errmsg);
            }
        } else {
            // 响应不是JSON格式，但请求成功
            qDebug() << "CommitFileToUrlCommand: 文件提交响应不是JSON格式，但请求成功";
            
            // 上传成功后，更新 kms_command.STATUS 为 COMPLETED
            if (m_databaseManager && !commitUrl.isEmpty()) {
                if (m_databaseManager->updateCommandStatusByCommitUrl(commitUrl, "commitfiletourl", "COMPLETED")) {
                    qDebug() << "CommitFileToUrlCommand: 成功更新命令记录状态，提交URL:" << commitUrl << "状态:COMPLETED";
                } else {
                    qDebug() << "CommitFileToUrlCommand: 更新命令记录状态失败，提交URL:" << commitUrl;
                }
            }
            
            // 提交成功后删除本地文件
            if (!localFilePath.isEmpty()) {
                QFile localFile(localFilePath);
                if (localFile.exists()) {
                    if (localFile.remove()) {
                        qDebug() << "CommitFileToUrlCommand: 成功删除本地文件:" << localFilePath;
                    } else {
                        qDebug() << "CommitFileToUrlCommand: 删除本地文件失败:" << localFilePath 
                                 << "错误:" << localFile.errorString();
                    }
                } else {
                    qDebug() << "CommitFileToUrlCommand: 本地文件不存在，无需删除:" << localFilePath;
                }
            }
            
            emit fileCommitCompleted(0, "文件提交成功");
        }
    } else {
        qDebug() << "CommitFileToUrlCommand: 文件提交失败:" << reply->errorString();
        
        // 请求失败，更新 kms_command.STATUS 为 FAILED
        if (m_databaseManager && !commitUrl.isEmpty()) {
            if (m_databaseManager->updateCommandStatusByCommitUrl(commitUrl, "commitfiletourl", "FAILED")) {
                qDebug() << "CommitFileToUrlCommand: 成功更新命令记录状态，提交URL:" << commitUrl << "状态:FAILED";
            } else {
                qDebug() << "CommitFileToUrlCommand: 更新命令记录状态失败，提交URL:" << commitUrl;
            }
        }
        
        emit fileCommitCompleted(reply->error(), "文件提交失败: " + reply->errorString());
    }
    
    reply->deleteLater();
}

